home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Deutsche Edition 1
/
Deutsche Edition 1.iso
/
amok
/
031-040
/
amok32
/
tasksupport
/
tasksupport.dok
< prev
next >
Wrap
Text File
|
1993-11-04
|
8KB
|
179 lines
======================================================================
Dokumentation zu "TaskSupport" Version 1.1
Autor: Nicolas Benezan, Postwiesenstr. 2, D7000 Stuttgart 60
======================================================================
Übersicht
* Kopierrecht
* Umfang des Projekts
* Einleitung
* Beschreibung der Prozeduren
* Demo- / Testprogramm
Kopierrecht
Das komplette Projekt (Quelltext, Dokumentation und Objectcode) ist
Public Domain Software. Es darf beliebig kopiert und verbreitet werden
solange...
* mein Name und dieser Kopierrechtshinweis erhalten bleiben,
* die Vollständigkeit des ganzen Projekts gewährleistet ist, und
* mit dem Vertrieb dieser Software kein Gewinn erwirtschaftet wird.
Die Kommerzielle Nutzung ohne meine ausdrückliche schriftliche
Genehmigung ist untersagt (über Gewinnbeteiligung läßt sich reden).
W i c h t i g: Dies gilt insbesondere auch für "schwarze Schafe" der
"PD"-Versandhäuser, die ganz offensichtlich Gewinn machen, was z.B. durch
ganzseitige Anzeigen in Zeitschiften erkennbar ist.
Verbesserungsvorschläge sind stets willkommen. Falls Sie Veränderungen
am Programm vornehmen, dokumentieren Sie diese bitte gut verständlich.
Es würde mich freuen, wenn Sie mich über größere Veränderungen oder
Erweiterungen in Kenntnis setzen würden.
(c) 1988 by Nicolas Benezan.
--------------------------------------------------------------------------
Ich möchte an dieser Stelle Bernd Preusing danken, der mir bei der
Realisierung dieses Moduls sehr geholfen hat.
--------------------------------------------------------------------------
Umfang des Projekts
Das komplette Projekt "TaskSupport" beinhaltet folgende Dateien:
* TaskSupport.dok Diese Dokumentation
* TaskSupport.def Definitionsmodul
* TaskSupport.mod Implementationsmodul
(Stand 12.Jan.1990)
Einleitung
Die Programmierung von eigenen Tasks führt aufgrund der folgenden
Schwierigkeiten leider oft zu Guru-Meditations:
* ExecSupport.CreateTask (zumindest ältere Versionen) haben einen Bug: sie
stürzen, wenn nicht mehr genügend Speicher vorhanden ist. Dies liegt an
der Dummheit von Exec.AllocEntry, das einen Fehler nicht durch NIL
sondern durch Bit 31 anzeigt, übrigens entgegen der Konvention, die
oberen 8 Bit einer Adresse nicht für Daten zu benutzen.
* Das Stack-Checking von Modula verwendet dummerweise nicht das Feld
Task^.spLower sondern eine eigene Variable Arts.stackTop. Hat das
Programm mehrere Tasks, dann ist diese natürlich normalerweise nicht
immer richtig gesetzt. Entweder man schaltet das Stack-Checking ganz ab,
oder man hofft auf den Zufall, daß der Stack des neuen Tasks an einer
höheren Adresse liegt als der des Haupttasks. Beides sehr unbefriedigende
Lösungen.
* Das Problem der korrekten Terminierung: Da jeder Task, der Teile des
gleichen Code-Segments benutzt wie das Hauptprogramm, spätestens dann
terminieren muß, wenn es das Hauptprogramm tut, muß jeder neu erzeugte
Task (ohne eigenes Code-Segment) auch irgendwann wieder gelöscht werden.
Es reicht jedoch nicht, einfach ein Exec.RemTask() oder ExecSupport.-
DeleteTask() in eine TermProcedure zu schreiben, den ohne besondere
Vorkehrungen wäre es auch möglich, daß der Task schon vorher terminierte,
und einen Task löschen den es nicht gibt...
Es ist übrigens auch keine Lösung, vorher mit FindTask nachzuschauen,
ob der Task noch existiert. Was ist, wenn man das Programm zweimal
startet, also dann existieren zwei Tasks mit gleichem Namen. Wenn jetzt
das eine Programm den Task des anderen findet und denkt SEIN task wäre
noch da, und diesen irrtümlicherweise löscht... nu ja, hallo Guru!
* Selbsterzeugte Tasks können normalerweise keine Dos-Prozeduren verwenden,
da ihnen die Process-Struktur fehlt (Das ist das, wo der ganze BCPL-Kram
drinsteht, unter anderem CurrentDir und verschiedenes fürs File-System).
Dos.CreateProc() anstelle von ExecSupport.CreateTask() hilft da auch
nicht, da es sehr schlecht dokumentiert und daher sehr schwierig
einzusetzten ist (es gelang mir auch nach längerem Experimentieren nicht,
einen Prozess zu erzeugen und wieder zu löschen, ohne daß jedesmal 24
Bytes geschluckt wurden).
* Es giebt immer wieder fehlerhafte Multitasking-Programme, die die
Prinzipien des gegenseitigen Ausschlusses (Forbid, Semaphoren) nicht
beachten, gegen Deadlocks nicht ausreichend vorbeugen oder ihre Resourcen
nicht mehr zurückgeben. Leider ist das Amiga-Betriebssystem hierbei sehr
ungnädig, der Programmierer hat die volle Verantwortung.
Mit dem Modul "TaskSupport" werden diese Fallen so weit wie es geht
umgangen. Es stellt Prozeduren zum Erzeugen und Löschen von Tasks
(bzw. Dos-Prozessen) zur Verfügung, die ein großes Maß an Absturzsicherheit
besitzen. Natürlich ist gegen den letzten Punkt kein Kraut gewachsen, da
muß jeder selbst aufpassen.
Beschreibung der Prozeduren
CreateTask
----------
Diese Prozedur diest zum Erzeugen und Starten eines neuen Tasks. Außer der
Prozedur, die als Task gestartet werden soll, müssen noch ein Name, die
Größe des Stacks und die Priorität angegeben werden.
Der Name ist für System-Debugger-Tools ganz nützlich. Aus ihm sollte
ersichtlich sein, zu welchem Programm der Task gehört, und falls es
meherere gibt, was er macht. Forsicht mit Exec.FindTask(). Sie können zwar
nach Tasks mit bestimmtem Namen suchen, rechnen Sie jedoch damit, daß es
mehrere Tasks mit gleichem Namen gibt. Wenn sie eindeutige Namen benötigen,
Verwenden Sie die Systemzeit zusammen mit Ihrem Programmnamen (z.B.
"TaskTest.SSSSSS.MMMMM", wobei S und M für "secs" und "micro" eines
"Timer.TimeVal"s stehen).
Die erforderliche Stackgröße hängt von der Tiefe der Prozedurverschach-
telung oder Rekursion ab. 1k ist Minimum, 4k Standard und 20k sollten auf
jeden Fall reichen. Das Stack-Checking darf (sollte auch) eingeschaltet
bleiben. Durch einen Trick (Launch/Switch-Prozeduren) wird sichergestellt,
daß Arts.stackTop immer richtig gesetzt ist.
Gehen Sie vorsichtig mit der Priorität um! geben Sie nur solchen Tasks eine
Priorität > 0, die relativ sparsam mit der Rechenzeit umgehen (oft warten,
aber schnell reagieren müssen), sonst wird das System blockiert.
Der Parameter "InitArg" ist eine spezielle Zugabe von TaskSupport. Es ist
möglich, dem neuen Task ein Argument (z.B. Zeiger auf ein RECORD) zu
übergeben (Parameter von TaskProc). Das ist besonders dann nützlich, wenn
dieselbe Prozedur mehrmals als Task gestartet wird, aber jedesmal auf
andere Daten wirken soll. In diesem Fall können nämlich keine globalen
Variablen zur Parameterübergabe verwendet werden.
Der neue Task erhält auch eine Dos.Process-Struktur, sodaß er auch
Dos-Prozeduren verwenden darf. Es sollte jedoch beachtet werden, daß sein
CurrentDir am Anfang auf NIL steht, also erst noch initialisiert werden
sollte. Wenn Sie dafür einen neuen FileLock Dos.Lock()en, achten Sie
darauf, ihn vor Beendigung des Tasks wieder zu UnLock()en.
Wenn der neu gestartete Task Speicher alloziert, sollten Sie am besten
das Modul "TaskMemory" oder "MemSystem" benutzen. Es ist damit
sichergestellt, daß der Speicher bei Beendigung des Tasks freigegeben wird
(Vorsicht: stellen Sie sicher, das andere Tasks nicht mehr auf solchen
freigegebenen Speicher zugreifen!).
DeleteTask
----------
Diese Prozedur bricht einen Task ab, entfernt den Task selbst und gibt
allen Speicher frei, den er (mit "TaskMemory" oder "MemSystem") alloziert
hat.
Es ist erlaubt, daß ein Task sich selbst löscht.
Existiert ein Task, der gelöscht werden soll, nicht mehr, wird der Aufruf
einfach ignoriert. Es ist auch nicht möglich, den Haupt-Task oder einen
Task, der nicht zum Programm gehört (der nicht mit TaskSupport.CreateTask
erzeugt wurde), zu löschen.
Wird das Hauptprogramm beendet, werden alle noch existierenden Tasks
automatisch gelöscht.
Demo- / Testprogramm
Ein Demoprogramm ist im Projekt "RingBuffers" enthalten (auch auf dieser
Diskette).